Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Using provider instead of HttpServletRequest in ServletJaxRsContextFactoryProvider #42

Merged
merged 6 commits into from
May 14, 2018

Conversation

ganeshs
Copy link

@ganeshs ganeshs commented Apr 24, 2018

This is the fix for pac4j/dropwizard-pac4j#43

@victornoel
Copy link
Member

@ganeshs FYI I won't be able to review this right now, but as soon as I can I will experiment with it.

Could you explain briefly why you had to change things for resteasy, what are the new dependencies for and if it means that resteasy users need a special setup for pac4j to work now?

Thanks for your help and patience :)

@ganeshs
Copy link
Author

ganeshs commented Apr 25, 2018

The change is to inject a javax.inject.provider instead httpservletrequest. For the resteasy module, I have modified the tests to use cdi. This means, the resteasy users will have to use cdi for injecting the provider. I have added a test that would act as an example for cdi integration.

@ganeshs
Copy link
Author

ganeshs commented May 5, 2018

@victornoel any update on this

Copy link
Member

@victornoel victornoel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I've reviewed it.
I'm not totally convinced this is the right solution for pac4j/dropwizard-pac4j#43 though... this seem to add more complexity to the already complex situation.

Until you fix this, I will try to better understand why it happens, it would be very helpful to have a reproduction of the original problem in dropwizard-pac4j :) if we can't find something more elegant then we will go with this.

@@ -15,13 +16,14 @@
* @since 1.0.0
*
*/
@Provider
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would prefer not to use @Provider.

In the past we used something like that but the problem was that depending on the use, it was problematic so we decided to let user explicitly define their own Provider class (see https://github.com/pac4j/jax-rs-pac4j/#jax-rs-autoscanning).

If I'm right, this shouldn't change anything for this PR since you register manually the provider below but maybe some more configuration will be needed in the tests?

resteasy/pom.xml Outdated
@@ -22,6 +22,7 @@
</dependencies>
</dependencyManagement>


Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remove this extra line

resteasy/pom.xml Outdated
<groupId>org.jboss.resteasy</groupId>
<artifactId>resteasy-cdi</artifactId>
<scope>test</scope>
<version>3.1.4.Final</version>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you factor this version number and the same one in dependencyManagement into a property named resteasy.version?

public class MyApp extends Application {
public static class MyApp extends Application {

private RestEasyUndertowServletRule rule = new RestEasyUndertowServletRule();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't seem coherent to have the rule here just to call getResources() on it!

I see you made the class static, but it is not needed at all. Please revert that as well as the calls to getResources() and getConfig() below.

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you move this with the test application? To me it has nothing to do here, it is only needed for resteasy with cdi, no? Or explain why it is needed here please

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As per the CDI specification to discover beans from the archive, we need to have beans.xml under META-INF folder in the archive. I have spent enough time in figuring out a workaround for this but no success yet.

Bean classes of enabled beans must be deployed in bean archives.
A library jar, EJB jar, application client jar or rar archive is a bean archive if it has a file named beans.xml in the META-INF directory.
https://docs.jboss.org/cdi/spec/1.0/html/packagingdeployment.html

In this case, the ServletJaxRsContextFactoryProvider has an @Inject on requestProvider and without the beans.xml in its jar, the requestProvider is not getting injected.

@victornoel I would be happy to fix if a solution is known. I don't have enough bandwidth to search for a solution right now. I completely agree with you that this is an unnecessary addition but definitely is harmless. Would really appreciate if we can go ahead for now and fix when a solution is available.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I agree, thank you for the explanation :)
Could you just add some comment in that file explaining why it is here exactly and maybe saying it is mainly because of resteasy/cdi?

ResteasyDeployment deployment = new ResteasyDeployment();
deployment.setInjectorFactoryClass("org.jboss.resteasy.cdi.CdiInjectorFactory");
deployment.setApplication(new MyApp());
DeploymentInfo di = server.undertowDeployment(deployment).setContextPath("/").setDeploymentName("DI")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

improve indentation (one call per line)

@@ -66,7 +72,13 @@ protected void before() throws Throwable {
System.setProperty("org.jboss.resteasy.port", "24257");
server = new UndertowJaxrsServer().start();

server.deploy(new MyApp());
ResteasyDeployment deployment = new ResteasyDeployment();
deployment.setInjectorFactoryClass("org.jboss.resteasy.cdi.CdiInjectorFactory");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer to use CdiInjectorFactory.class.getName() instead

resteasy/pom.xml Outdated
</dependency>
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what is this for?

deployment.setInjectorFactoryClass("org.jboss.resteasy.cdi.CdiInjectorFactory");
deployment.setApplication(new MyApp());
DeploymentInfo di = server.undertowDeployment(deployment).setContextPath("/").setDeploymentName("DI")
.setClassLoader(RestEasyUndertowServletRule.class.getClassLoader())
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prefer to use getClass().getClassLoader()

deployment.setApplication(new MyApp());
DeploymentInfo di = server.undertowDeployment(deployment).setContextPath("/").setDeploymentName("DI")
.setClassLoader(RestEasyUndertowServletRule.class.getClassLoader())
.addListeners(Servlets.listener(org.jboss.weld.environment.servlet.Listener.class));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not use fqdn if possible, it is better to have all imports in import section so we can quickly see the dependencies of the class.

Copy link
Member

@victornoel victornoel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We are almost good, thanks for your patience :)

Could you also:

  • refer to ServletJaxRsContextFactoryProvider by class instead of instance also in jersey's implementations
  • add some words in README about:
    • the need to refer to those classes (and others maybe?) by class and not instance when initializing the jax-rs environment (or simply just update the examples)
    • the need to use cdi (just pointing to the test will be enough) for resteasy

Thanks again :)

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="UTF-8"?>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I agree, thank you for the explanation :)
Could you just add some comment in that file explaining why it is here exactly and maybe saying it is mainly because of resteasy/cdi?

@Context
private HttpServletRequest request;
@Inject
private javax.inject.Provider<HttpServletRequest> requestProvider;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can now use an import instead :)

@ganeshs
Copy link
Author

ganeshs commented May 14, 2018

@victornoel Addressed the changes requested.

Copy link
Member

@victornoel victornoel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we are almost there :)

README.md Outdated
@@ -36,7 +36,7 @@ These filters can be directly registered by hand, or instead, the following feat
5) Container/Implementation-specific Providers and Features extend the basic functionality provided by the generic ones

- The `Pac4JValueFactoryProvider` enables injection of the security profile in resource method (for Apache Jersey <2.26, see [#30](https://github.com/pac4j/jax-rs-pac4j/issues/30))
- The `ServletJaxRsContextFactoryProvider` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` (for Servlet-based JAX-RS implementations, e.g., Jersey on Netty or Grizzly Servlet, Resteasy on Undertow).
- The `ServletJaxRsContextFactoryProvider` provides session handling (and thus indirect clients support) by replacing the generic `JaxRsContextFactoryProvider` (for Servlet-based JAX-RS implementations, e.g., Jersey on Netty or Grizzly Servlet, Resteasy on Undertow). This provider returns a RequestScoped context and so should be added as a class `ServletJaxRsContextFactoryProvider.class` instead of instance `new ServletJaxRsContextFactoryProvider()`. For RestEasy, you need to include `resteasy-cdi` support to your project. Refer to the tests in `resteasy-pac4j` module.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, but that's not the right place where to do that.
This sentence should be kept as it is and the examples below should be updated as well as a little line of explanation about resteasy-cdi next to the section related to resteasy.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Hope this works.

Copy link
Member

@victornoel victornoel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, last one, there is an error in the example (and a typo)

@Override
public Set<Class<?>> getClasses() {
Set<Class<?>> classes = new HashSet<>();
classes.add(ServletJaxRsContextFactoryProvider.class);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pac4JProfileInjectorFactory needs to be moved too, I tested and it doesn't work without it

README.md Outdated
@@ -50,7 +50,7 @@ You need to add a dependency on:

- jax-rs-pac4j
1. for Jersey (<2.26) : the `jersey-pac4j` library (<em>groupId</em>: **org.pac4j**, *version*: **3.0.0**)
2. for Resteasy : the `resteasy-pac4j` library (<em>groupId</em>: **org.pac4j**, *version*: **3.0.0**)
2. for Resteasy : the `resteasy-pac4j` library (<em>groupId</em>: **org.pac4j**, *version*: **3.0.0**) and resteasy-cdi for CDI support
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

add backquotes around resteasy-cdi please

@victornoel victornoel merged commit d669e9f into pac4j:master May 14, 2018
@victornoel
Copy link
Member

Thanks @ganeshs, great work!

victornoel added a commit that referenced this pull request May 19, 2018
Using provider instead of HttpServletRequest in ServletJaxRsContextFactoryProvider
@victornoel
Copy link
Member

This was backported to 2.x too :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants